package com.jwsoft.manager.core.dao.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bifang.module.base.common.vo.tree.TreeVO;
import com.jwsoft.manager.common.vo.addressParse.Address;
import com.jwsoft.manager.core.dao.model.EduAddressTreeInitial;
import com.jwsoft.manager.core.dao.model.EduAddressTreeOriginal;
import com.jwsoft.manager.core.dao.mapper.EduAddressTreeOriginalMapper;
import com.jwsoft.manager.core.dao.service.EduAddressTreeOriginalService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 服务实现类
 *
 * @author zhiyuan
 * @since 2024-01-08
 */
@Service
public class EduAddressTreeOriginalServiceImpl extends ServiceImpl<EduAddressTreeOriginalMapper, EduAddressTreeOriginal> implements EduAddressTreeOriginalService {

    @Override
    public List<EduAddressTreeOriginal> getAllLinkByOriginalId(Long treeId) {
        ArrayList<EduAddressTreeOriginal> originalLink = new ArrayList<>();
        EduAddressTreeOriginal original = baseMapper.selectById(treeId);
        if (original == null) {
            return originalLink;
        }
        while (!ObjectUtils.isEmpty(original)) {
            originalLink.add(original);
            QueryWrapper<EduAddressTreeOriginal> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(EduAddressTreeOriginal::getAddressId, original.getParentId());
            original = baseMapper.selectOne(queryWrapper);
        }
        Collections.reverse(originalLink);
        return originalLink;
    }

    /**
     * 根据id获取所有子节点数据
     * @param addressId
     * @return
     */
    @Override
    public List<EduAddressTreeOriginal> getAllDescendants(Long addressId) {
        List<EduAddressTreeOriginal> descendants = new ArrayList<>();
        List<EduAddressTreeOriginal> childNodes = list(Wrappers.<EduAddressTreeOriginal>lambdaQuery()
                .select(EduAddressTreeOriginal::getAddressId, EduAddressTreeOriginal::getAreaName, EduAddressTreeOriginal::getParentId)
                .eq(EduAddressTreeOriginal::getParentId, addressId));
        collectDescendants(childNodes, descendants);
        return descendants;
    }
    private void collectDescendants(List<EduAddressTreeOriginal> childNodes, List<EduAddressTreeOriginal> descendants) {
        if (childNodes == null || childNodes.isEmpty()) {
            return;
        }
        for (EduAddressTreeOriginal childNode : childNodes) {
            descendants.add(childNode);  // 添加当前子节点
            List<EduAddressTreeOriginal> grandchildren = list(Wrappers.<EduAddressTreeOriginal>lambdaQuery()
                    .select(EduAddressTreeOriginal::getAddressId, EduAddressTreeOriginal::getAreaName, EduAddressTreeOriginal::getParentId)
                    .eq(EduAddressTreeOriginal::getParentId, childNode.getAddressId()));
            collectDescendants(grandchildren, descendants); // 递归获取孙子节点，并添加到结果集中
        }
    }
    @Override
    public List<TreeVO> builderTreeList(List<TreeVO> treeVOList) {
        if (treeVOList == null || treeVOList.isEmpty()) {
            return new ArrayList<>();
        }
        //最后需要返回的树形list结构
        List<TreeVO> respTreeNodeList = new LinkedList<>();
        //存储所有节点的id，用来判断是否为根节点数据，存在idSet中的数据，就表示一定为子节点
        Set<String> idSet = new HashSet<>(treeVOList.size());
        // 拷贝数据
        for (TreeVO treeVO : treeVOList) {
            idSet.add(treeVO.getKey());
            respTreeNodeList.add(treeVO);
        }
        Map<String, List<TreeVO>> parentMap = treeVOList.stream().collect(Collectors.groupingBy(TreeVO::getParentKey));
        Iterator<TreeVO> iterator = respTreeNodeList.iterator();
        TreeVO node;
        while (iterator.hasNext()) {
            node = iterator.next();
            // 获取当前结点的子节点集合
            node.setChildren(parentMap.get(node.getKey()));
            // 如果父id在id集合中存在，则说明他不是根节点，移除
            if (idSet.contains(node.getParentKey())) {
                iterator.remove();
            }
        }
        return respTreeNodeList;
    }
}
